home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / rpg / crossfir.92 / crossfir / crossfire-0.92.5 / server / resurrection.c < prev    next >
C/C++ Source or Header  |  1996-07-24  |  8KB  |  303 lines

  1. /*
  2.  * static char *rcsid_resurrection_c =
  3.  *   "$Id: resurrection.c,v 1.4 1996/01/02 11:48:38 master Exp $";
  4.  */
  5.  
  6. /*
  7.     CrossFire, A Multiplayer game for X-windows
  8.  
  9.     Copyright (C) 1992 Frank Tore Johansen
  10.  
  11.     This program is free software; you can redistribute it and/or modify
  12.     it under the terms of the GNU General Public License as published by
  13.     the Free Software Foundation; either version 2 of the License, or
  14.     (at your option) any later version.
  15.  
  16.     This program is distributed in the hope that it will be useful,
  17.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.     GNU General Public License for more details.
  20.  
  21.     You should have received a copy of the GNU General Public License
  22.     along with this program; if not, write to the Free Software
  23.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  24.  
  25.     The author can be reached via e-mail to frankj@ifi.uio.no.
  26. */
  27. /*  the contents of this file were create solely by peterm@soda.berkeley.edu
  28.     all of the above disclaimers apply.  */
  29.  
  30. #include <global.h>
  31. #ifndef __CEXTRACT__
  32. #include <sproto.h>
  33. #endif
  34. #include <spells.h>
  35. #include <errno.h>
  36. #ifdef sequent
  37. /* stoopid sequent includes don't do this like they should */
  38. extern char * sys_errlist[];
  39. extern int sys_nerr;
  40. #endif
  41. extern char **classname;
  42. extern object *objects;
  43.  
  44.  
  45.  
  46. void dead_player(object *op)
  47. {
  48.   char filename[MAX_BUF];
  49.   char newname[MAX_BUF];
  50.   char path[MAX_BUF];
  51.  
  52. /*  set up our paths/strings...  */
  53. #ifdef SAVE_HOMEDIR
  54.   sprintf(path,"%s/%s/%s",(char *) getenv("HOME"),PlayerDir,op->name);
  55. #else
  56.   sprintf(path,"%s/%s/%s",LibDir,PlayerDir,op->name);
  57. #endif
  58.  
  59.   strcpy(filename,path);
  60.   strcat(filename,".pl");
  61.   strcpy(newname,filename);
  62.   strcat(newname,".dead");
  63.   if(!rename(filename,newname)) {
  64.     perror(filename);
  65.     perror(newname);
  66.   }
  67. }
  68.  
  69.  
  70.  
  71.  
  72. /*  raise_dead by peterm and mehlhaff@soda.berkeley.edu  */
  73. /*  *op  --  who is doing the resurrecting
  74.     dir  --  direction the spell is cast
  75.     spell_type  --  which spell was cast 
  76. */
  77. int cast_raise_dead_spell(object *op,int dir,int spell_type, object * corpseobj)
  78. {
  79.   object *temp, *newob;
  80.   char name_to_resurrect[MAX_BUF];
  81.   int leveldead=25;
  82.  
  83.  
  84.   if(corpseobj == NULL){
  85.       /*  First we need to find a corpse, if any.  */
  86.       for(temp=get_map_ob(op->map,op->x+freearr_x[dir],op->y+freearr_y[dir]);
  87.           temp!=NULL;
  88.             temp=temp->above)
  89.           /* really need a better way to spot corpseobjects */
  90.           if(temp->type == 157 && temp->immune==262143)  /* corpses immune to everything, so that they cannot be destroyed.  */
  91.             break;
  92.          } else {
  93.       temp = corpseobj;
  94.          }
  95.  
  96.    if(temp == NULL&&(spell_type==SP_RAISE_DEAD||spell_type==SP_RESURRECTION)){
  97.         new_draw_info(NDI_UNIQUE, 0,op, "You need a body for this spell.");
  98.         return 0;
  99.    }
  100.  
  101.    strcpy(name_to_resurrect, temp->name );
  102.  
  103.      /* no matter what, we fry the corpse.  */
  104.    if( temp) if(temp->map){
  105.        /* replace corpse object with a burning object */
  106.        newob = arch_to_object(find_archetype("burnout"));
  107.        if(newob != NULL){
  108.           newob->x = temp->x;
  109.           newob->y = temp->y;
  110.           insert_ob_in_map( newob, temp->map);
  111.        }
  112.     leveldead=temp->level;
  113.        remove_ob(temp);
  114.        free_object(temp);
  115.    }
  116.    /* chance it fails to resurrect? -- implement here */
  117.    /* also, chances you accidentally summon death or worse... */
  118.  
  119.   switch(spell_type)
  120.     {
  121.     case SP_RAISE_DEAD:
  122.       /*  see if this spell fails, if so then summon some
  123.           undead. levels[1] is important, see below*/
  124.       if(resurrection_fails(op->level,leveldead))
  125.         {
  126.           summon_hostile_monsters(op,5,"demon");
  127.           summon_hostile_monsters(op,3,"skull");
  128.           return 1;
  129.     }
  130.       return resurrect_player(op,name_to_resurrect,spell_type);
  131.  
  132.  
  133.     case SP_RESURRECTION:
  134.       if(resurrection_fails(op->level,leveldead))
  135.         {
  136.           summon_hostile_monsters(op,5,"skull");
  137.           summon_hostile_monsters(op,3,"lich");
  138.           return 1;
  139.     }
  140.       return resurrect_player(op,name_to_resurrect,spell_type);
  141.  
  142.  
  143.     case SP_REINCARNATION:
  144.       if(resurrection_fails(op->level,0))
  145.         {
  146.           summon_hostile_monsters(op,5,"lich");
  147.           summon_hostile_monsters(op,3,"demilich");
  148.           summon_hostile_monsters(op,1,"spectre");
  149.           return 1;
  150.     }
  151.       return resurrect_player(op,name_to_resurrect,spell_type);
  152.     }
  153.    return 1;
  154. }
  155.  
  156.  
  157. int resurrection_fails(int levelcaster,int leveldead)
  158. {
  159.   int chance=9;
  160. /*  scheme:  equal in level, 50% success.
  161.     +5 % for each level below, -5% for each level above.
  162.     minimum 20%
  163.     */
  164.   chance+=levelcaster-leveldead;
  165.   if(chance<4) chance=4;
  166.   if(chance>RANDOM()%20) return 0;  /* resurrection succeeds */
  167.   return 1;
  168. }
  169.  
  170.  
  171. /*  name of the person to resurrect and which spell was used
  172. to resurrect  */
  173. int resurrect_player(object *op,char *playername,int rspell)
  174. {
  175.   FILE *deadplayer,*liveplayer;
  176.  
  177.   char oldname[MAX_BUF];
  178.   char newname[MAX_BUF];
  179.   char path[MAX_BUF];
  180.   char buf[MAX_BUF];
  181.   char buf2[MAX_BUF];
  182.  
  183.   const char *races[]= { "barbarian","cleric", "elf","human","mage","ninja","priest",
  184.             "swashbuckler","thief","viking","warrior","wizard" };
  185.  
  186.   long int exp;
  187.   int Con;
  188.  
  189. /*  set up our paths/strings...  */
  190. #ifdef SAVE_HOMEDIR
  191.   sprintf(path,"%s/%s/%s",(char *) getenv("HOME"),PlayerDir,playername);
  192. #else
  193.   sprintf(path,"%s/%s/%s",LibDir,PlayerDir,playername);
  194. #endif
  195.  
  196.   strcpy(newname,path);
  197.   strcat(newname,".pl");
  198.  
  199.   strcpy(oldname,newname);
  200.   strcat(oldname,".dead");
  201.  
  202.   if(! (deadplayer=fopen(oldname,"r"))) {
  203.     new_draw_info_format(NDI_UNIQUE, 0, op,
  204.     "The soul of %s cannot be reached.",playername);
  205.     return 0;
  206.     }
  207.  
  208.   if(!access(newname,0)) {
  209.     new_draw_info_format(NDI_UNIQUE, 0, op,
  210.     "The soul of %s has already been reborn!",playername);
  211.     fclose(deadplayer);
  212.     return 0;
  213.     }
  214.  
  215.   if(! (liveplayer=fopen(newname,"w")))
  216.     {
  217.     new_draw_info_format(NDI_UNIQUE, 0, op,
  218.     "The soul of %s cannot be re-embodied at the moment.",playername);
  219.     LOG(llevError,"Cannot write player in ressurect_player!\n");
  220.     fclose(deadplayer);
  221.     return 0;
  222.     }
  223.  
  224.   while (!feof(deadplayer))
  225.     {    fgets(buf,255,deadplayer);
  226.     sscanf(buf,"%s",buf2);
  227.     if( ! (strcmp(buf2,"exp"))) {
  228.         sscanf(buf,"%s %ld",buf2,&exp);
  229.         switch(rspell) {
  230.         case SP_RAISE_DEAD:
  231.         exp-=exp/20;
  232.         break;
  233.         case SP_RESURRECTION:
  234.         exp-=exp/10;
  235.         break;
  236.         case SP_REINCARNATION:
  237.         exp-=exp/5;
  238.         break;
  239.         }
  240.         sprintf(buf,"exp %ld\n",exp);
  241.     }
  242.       if(! (strcmp(buf2,"Con"))) {
  243.     sscanf(buf,"%s %d",buf2,&Con);    
  244.     switch(rspell) {
  245.         case SP_RAISE_DEAD:
  246.         Con-=2;
  247.         break;
  248.         case SP_RESURRECTION:
  249.         Con-=1;
  250.         break;
  251.     }
  252.     sprintf(buf,"Con %d\n",Con);
  253.       }
  254.      if(rspell==SP_REINCARNATION) {
  255.     if(! (strcmp(buf2,"race"))) {
  256.         sprintf(buf,"race %s\n",races[RANDOM()%12+1]);
  257.     }
  258.      }
  259.   fputs(buf,liveplayer);
  260.     }
  261.   fclose(liveplayer);
  262.   fclose(deadplayer);
  263.   unlink(oldname);
  264.   new_draw_info_format(NDI_UNIQUE, 0, op,
  265.     "%s lives again!",playername);
  266.  
  267.   return 1;
  268. }
  269.         
  270.  
  271. void dead_character(char *name) {
  272.   char buf[MAX_BUF];
  273.   char buf2[MAX_BUF];
  274.  
  275. #ifdef SAVE_HOMEDIR
  276.   sprintf(buf,"%s/%s/%s.pl",(char *) getenv("HOME"),PlayerDir,name);
  277. #else
  278.   sprintf(buf,"%s/%s/%s.pl",LibDir,PlayerDir,name);
  279. #endif
  280.   /*  peterm:  create a .dead filename....  ***.pl.dead  */
  281.   strcpy(buf2,buf);
  282.   strcat(buf,".dead");
  283.   if(rename(buf2,buf)== -1 && debug){
  284.     fprintf(stderr, "Crossfire character rename to dead: %s --", buf);
  285.     perror("rename()");
  286.   }
  287. }
  288.  
  289.  
  290. int dead_player_exists(char *name) {
  291.   char buf[MAX_BUF];
  292.  
  293. #ifdef SAVE_HOMEDIR
  294.   sprintf(buf,"%s/%s/%s",(char *) getenv("HOME"),PlayerDir,name);
  295. #else
  296.   sprintf(buf,"%s/%s/%s",LibDir,PlayerDir,name);
  297. #endif
  298.   strcat(buf,".pl.dead");
  299.   return !(access(buf,0));
  300. }
  301.  
  302.  
  303.